using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using DotNetNuke.Modules.NBrightEspace.Components;
using DotNetNuke.Services.Exceptions;
using NBrightCore.common;
using NBrightCore.render;
using NBrightDNN;

namespace DotNetNuke.Modules.NBrightEspace
{

    /// -----------------------------------------------------------------------------
    /// <summary>
    /// The EditNBrightEspace class is used to manage content
    /// </summary>
    /// -----------------------------------------------------------------------------
    public partial class InDirectPay : EspaceModuleBase
    {

        #region Event Handlers

        private const string EntityTypeCode = "INDIRECTP"; // change for DB records

        override protected void OnInit(EventArgs e)
        {
            //Set base EntityTypeCode, MUST be done for all NBright child ctrls before OnInit
            base.EntityTypeCode = EntityTypeCode;
            
            base.OnInit(e);
            
            //initalize the repeater template based on what we want to see, a list or editing details.
            if (base.ItemId=="")
            {// itemid is blank so display the list
                rpData.Visible = false;

                //All list display functions are processed via the parent class, we just initiallize here.
                base.OnInitActivateList(true, true, MapPath(ControlPath));

            }
            else
            {// itemid is not blank, so display the detail template.
                rpData.ItemTemplate = new GenXmlTemplate(TemplCtrl.GetTemplateData(EntityTypeCode + "_Detail.html", Utils.GetCurrentCulture()));
                rpInstallments.ItemTemplate = new GenXmlTemplate(TemplCtrl.GetTemplateData(EntityTypeCode + "_Installments.html", Utils.GetCurrentCulture()));
                phInstallmentsH.Controls.Add(new LiteralControl(TemplCtrl.GetTemplateData(EntityTypeCode + "_InstallmentsH.html", Utils.GetCurrentCulture())));
                phInstallmentsF.Controls.Add(new LiteralControl(TemplCtrl.GetTemplateData(EntityTypeCode + "_InstallmentsF.html", Utils.GetCurrentCulture())));
                rpAllocated.ItemTemplate = new GenXmlTemplate(TemplCtrl.GetTemplateData(EntityTypeCode + "_Allocated.html", Utils.GetCurrentCulture()));
                phAllocatedH.Controls.Add(new LiteralControl(TemplCtrl.GetTemplateData(EntityTypeCode + "_AllocatedH.html", Utils.GetCurrentCulture())));
                phAllocatedF.Controls.Add(new LiteralControl(TemplCtrl.GetTemplateData(EntityTypeCode + "_AllocatedF.html", Utils.GetCurrentCulture())));
            }

        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (Page.IsPostBack == false)
            {
                PageLoad();
            }
        }

        private void PageLoad()
        {
            try
            {

                if (UInfo.SelType == "client")
                {// return to control from selection page.
                    base.UpdateSelected("client");
                }

                if (base.ItemId=="")
                {

                    //set default filter
                    if (String.IsNullOrEmpty(UInfo.SearchClearAfter))
                    {
                        UInfo.SearchFilters = " and ( ([xmlData].value('(genxml/hidden/dblallocatedamt)[1]', 'nvarchar(10)')) collate Latin1_General_CI_AI != ([xmlData].value('(genxml/textbox/txtamtpay)[1]', 'nvarchar(10)')) )";
                        UInfo.SearchOrderby = " Order by [xmlData].value('(genxml/textbox/datepay)[1]', 'nvarchar(50)') DESC ";
                        UInfo.Save();
                    }

                    // display list                    
                    base.BindListData();
                }
                else
                {// display the detail
                    base.DoDetail(rpData);
                    PopulateDetail(Convert.ToInt32(base.ItemId));
                }
            }
            catch (Exception exc) //Module failed to load
            {
                UInfo.ClearSearchData();
                Exceptions.ProcessModuleLoadException(this, exc);
            }
        }



        #endregion

        #region  "Events "

        protected void CtrlItemCommand(object source, RepeaterCommandEventArgs e)
        {
            var cArg = e.CommandArgument.ToString();

            switch (e.CommandName.ToLower())
            {
                case "new":
                    Response.Redirect(EditUrl("itemid", "0", EntityTypeCode), true);
                    break;
                case "update":
                    UpdateData();
                    Response.Redirect(EditUrl(EntityTypeCode));
                    break;
                case "cancel":
                    Response.Redirect(EditUrl(EntityTypeCode));
                    break;
                case "delete":
                    UnAllocateAllPayments(Convert.ToInt32(base.ItemId));
                    base.DeleteData(rpData);
                    Response.Redirect(EditUrl(EntityTypeCode));
                    break;
                case "selectclient":
                    UpdateData();
                    UInfo.SelType = "client";
                    UInfo.RtnSelUrl = EditUrl("itemid", base.ItemId, EntityTypeCode);
                    UInfo.RtnUrl = EditUrl("itemid", base.ItemId, EntityTypeCode);
                    UInfo.Save();
                    Response.Redirect(EditUrl("ClientSel"));
                    break;
                case "alloc":
                    UpdateData();
                    Response.Redirect(EditUrl("itemid", base.ItemId, EntityTypeCode), true);
                    break;
                case "deletealloc":
                    UnAllocatePayment(Convert.ToInt32(cArg));
                    Response.Redirect(EditUrl("itemid", base.ItemId, EntityTypeCode), true);
                    break;

            }

        }

        #endregion

        #region "populate methods"


        private void PopulateDetail(int ItemID)
        {
            double totalAllocated = 0;

            totalAllocated = PopulateAllocated(ItemID);

            GenXmlFunctions.SetHiddenField(rpData, "dblAllocatedAmt", totalAllocated.ToString(""));
            GenXmlFunctions.SetField(rpData, "lblallocatedamt", totalAllocated.ToString("0.00"));

            if (!string.IsNullOrEmpty(Utils.RequestParam(Context, "Err")))
            {
                //error on entered allocated amount, display message
                GenXmlFunctions.SetField(rpData, "lblmsg", "Invalid Allocated Amount");
            }
            else
            {
                GenXmlFunctions.SetField(rpData, "lblmsg", "");
            }

            //hide the client button, if a client has been already selected
            string cID = null;
            cID = GenXmlFunctions.GetHiddenField(rpData, "ClientID");
            if (!string.IsNullOrEmpty(cID))
            {
                GenXmlFunctions.HideField(rpData, "cmdSelectClient");
            }

            string aPay = null;
            aPay = GenXmlFunctions.GetField(rpData, "txtAmtPay");
            if (Utils.IsNumeric(aPay))
            {
                if (Math.Round(totalAllocated, 2) < Math.Round(Convert.ToDouble(aPay), 2))
                {
                    PopulateUnpayedInstallments();
                    CalcAllocatedPay(Math.Round(Convert.ToDouble(aPay), 2) - Math.Round(totalAllocated, 2));
                }
            }
        }

        private double PopulateAllocated(int ItemID)
        {

            var objCtrl = new EspaceController();

            var l = objCtrl.GetList(-1,-1,"INDIRECTP" + ItemID.ToString(""));

            double totalAllocated = 0;

            rpAllocated.DataSource = l;
            rpAllocated.DataBind();

            foreach (var obj in l)
            {
                totalAllocated += Convert.ToDouble(obj.GetXmlProperty("genxml/hidden/dblallocated"));
            }

            return Math.Round(totalAllocated, 2);

        }

        private void PopulateUnpayedInstallments()
        {
            var objCtrl = new EspaceController();

            var cID = GenXmlFunctions.GetHiddenField(rpData, "clientid");
            
            var strSqlFilter = " and [XMLData].value('(genxml/hidden/clientid)[1]', 'nvarchar(20)') = '" + cID + "' ";
            strSqlFilter += " and [XMLData].value('(genxml/hidden/dbltotaldue)[1]', 'money') > 0 ";
            strSqlFilter += " and [XMLData].value('(genxml/checkbox/chkdirectpay)[1]', 'nvarchar(10)') != 'True' ";
            
            const string strSqlOrderBy = " order by [XMLData].value('(genxml/hidden/dtedate)[1]', 'nvarchar(20)') ";

            var l = objCtrl.GetList(-1,-1,"INSTALLMENT%",strSqlFilter,strSqlOrderBy);

            rpInstallments.DataSource = l;
            rpInstallments.DataBind();

        }
#endregion

        #region "presistance methods"


        private void UpdateData()
        {
            if (Page.IsValid)
            {
                //extra processing for allocated payments
                if (GetAmtToAllocate() < GetAllocatedPay())
                {
                    Response.Redirect(EditUrl("itemid", base.ItemId, EntityTypeCode, new string[] {"Err=1"}), true);
                }
                else
                {
                    // Does standard update of template form
                    var objInfo = (NBrightInfo)base.UpdateDetailNoValidate(rpData, EntityTypeCode,"");
                    var objCtrl = new EspaceController();

                    // Do any special updates that are required.
                    if (string.IsNullOrEmpty(GenXmlFunctions.GetHiddenField(rpData, "paymentref")))
                    {
                        //if ClientRef doesn't exist create it
                        GenXmlFunctions.SetHiddenField(rpData, "paymentref", "PA3" + objInfo.ItemID.ToString("000000") + "-" + Convert.ToString(DateTime.Now.Year).Substring(2, 2));
                        objInfo.XMLData = GenXmlFunctions.GetGenXml(rpData);
                        objCtrl.Update(objInfo);
                    }
                    if (Utils.IsNumeric(base.ItemId))
                    {
                        UpdateAllocatedAmts(Convert.ToInt32(base.ItemId));

                        //update the data again after calculating amount allocated
                        GenXmlFunctions.SetHiddenField(rpData, "dblallocatedamt", objCtrl.GetAlreadyAllocatedPay(ItemId).ToString(""));
                        // update client detail for search anbd list 
                        var cid = GenXmlFunctions.GetHiddenField(rpData, "clientid");
                        if (Utils.IsNumeric(cid))
                        {
                            var objC = ObjCtrl.Get(Convert.ToInt32(cid));
                            GenXmlFunctions.SetHiddenField(rpData, "clientref", objC.GetXmlProperty("genxml/textbox/txtclientref"));
                            GenXmlFunctions.SetHiddenField(rpData, "clientname", objC.GetXmlProperty("genxml/textbox/txtclientname"));
                            GenXmlFunctions.SetHiddenField(rpData, "companyname", objC.GetXmlProperty("genxml/textbox/txtcompanyname"));
                        }

                        objInfo.XMLData = GenXmlFunctions.GetGenXml(rpData);
                        objCtrl.Update(objInfo);
                    }
                }

            }
        }



        #endregion

        #region "General Methods"


        private double GetAmtToAllocate()
        {
            double amt = 0;
            double payAmt = 0;
            double allocAmt = 0;
            string strTemp = "";

            strTemp = GenXmlFunctions.GetField(rpData, "txtAmtPay");
            if (Utils.IsNumeric(strTemp))
            {
                payAmt = Math.Round(Convert.ToDouble(strTemp), 2);
            }
            else
            {
                payAmt = 0;
            }
            var objCtrl = new EspaceController();
            allocAmt = objCtrl.GetAlreadyAllocatedPay(ItemId);

            amt = payAmt - allocAmt;
            if (amt < 0)
                amt = 0;
            return Math.Round(amt, 2);
        }

        private void CalcAllocatedPay(double AmtToAllocate)
        {

            AmtToAllocate = Math.Round(AmtToAllocate, 2);

            foreach (RepeaterItem dlitem in rpInstallments.Items)
            {
                if (AmtToAllocate > 0)
                {
                    double amt = 0;
                    double due = 0;

                    var strTemp = "";

                    var blnAllocate = true;
                    var hid = (HtmlGenericControl)dlitem.FindControl("DirectPayment");
                    if ((hid != null)) //Don't auto allocate to direct payments.
                    {
                        if (hid.Attributes["value"] == "True")
                        {
                            blnAllocate = false;
                        }
                    }

                    if (blnAllocate)
                    {

                        hid = (HtmlGenericControl)dlitem.FindControl("ItemID");
                        if ((hid != null))
                        {
                            var objCtrl = new EspaceController();
                            var objInfo = ObjCtrl.Get(Convert.ToInt32(hid.Attributes["value"]));
                            strTemp = objInfo.GetXmlProperty("genxml/hidden/dbltotaldue");
                        }
                        if (Utils.IsNumeric(strTemp))
                        {
                            due = Math.Round(Convert.ToDouble(strTemp), 2);
                        }
                        else
                        {
                            due = 0;
                        }
                        if (due < AmtToAllocate)
                        {
                            amt = due;
                        }
                        else
                        {
                            amt = Math.Round(Convert.ToDouble(AmtToAllocate), 2);
                        }
                        var tb1 = (TextBox) dlitem.FindControl("txtAllocated");
                        if (tb1 != null)
                        {
                            tb1.Text = amt.ToString("");
                            AmtToAllocate = AmtToAllocate - amt;
                        }

                    }
                }
            }
        }

        private double GetAllocatedPay()
        {
            double amt = 0;
            foreach (RepeaterItem dlitem in rpInstallments.Items)
            {
                var tb1 = (TextBox) dlitem.FindControl("txtAllocated");
                if ((tb1 != null))
                {
                    if (Utils.IsNumeric(tb1.Text))
                    {
                        amt = amt + Math.Round(Convert.ToDouble(tb1.Text), 2);
                    }
                }
            }
            return Math.Round(amt, 2);
        }

        private void UnAllocateAllPayments(int PayItemID)
        {
            var objCtrl = new EspaceController();
            var l = objCtrl.GetList(-1,-1,"INDIRECTP" + PayItemID.ToString(""));

            foreach (var obj in l)
            {
                objCtrl.UnAllocatePayment(obj.ItemID);
            }
        }


        private void UnAllocatePayment(int AllocItemID)
        {
            var objCtrl = new EspaceController();
            objCtrl.UnAllocatePayment(AllocItemID);
        }

        private void UpdateAllocatedAmts(int ItemID)
        {
            var objCtrl = new EspaceController();

            string xmlData = "";
            string AmtAlloc = null;
            double AmtTotal = 0;

            AmtTotal = 0;

            foreach (RepeaterItem dItem in rpInstallments.Items)
            {
                //calculate total
                AmtAlloc = GenXmlFunctions.GetField(rpInstallments, "txtAllocated", dItem.ItemIndex);
                if (Utils.IsNumeric(AmtAlloc))
                {
                    if (Convert.ToDouble(AmtAlloc) > 0)
                    {
                        AmtTotal += Math.Round(Convert.ToDouble(AmtAlloc), 2);
                        var insID = GenXmlFunctions.GetField(rpInstallments, "ItemID", dItem.ItemIndex);
                        objCtrl.AllocatePayment(PortalSettings, ItemID, Convert.ToInt32(insID), Convert.ToDouble(AmtAlloc), ModulePath, MapPath(ControlPath));
                    }
                }
            }

            GenXmlFunctions.SetHiddenField(rpData, "dblAllocatedAmt", AmtTotal.ToString(""));

        }

        #endregion

    }

}